#coding=utf-8

'''
Created on 2011-9-4

@author: Administrator
'''
from ripper.core.Storage import db
from ripper.core.Item import get_item_by_name
from ripper.handler.HttpHandler import HttpHandler
import os
from ripper.core.Exceptions import DownloadException
from ripper.handler.TorrentDownload import canDownload, TorrentDownloader
from ripper.handler.images import Thumbnail
from httplib import InvalidURL

# 需要下载的属性类型
NEED_DOWNLOAD = ['image', 'image[]', 'file', 'file[]', 'torrent', 'torrents']


class DataObj(object):
    '''
    classdocs
    '''


    def __init__(self, data, property , item, handler):
        '''
        Constructor
        '''
        self.item = item # 全局配置模板
        self.property = property # 单个属性配置模板
        self.handler = handler
        self.data = data # 一条采集记录数据
        
    # 下载属性
    # 如image类型
    def download(self):
        
        # 最多下载失败次数
        MAX_FAILS_ALLOW = 5
        
        if not self.is_need_download():
            return
        res = self.item.get_property('resource')
        dirName = '' # 下载目标文件夹
        resRoot = res['root'] # 配置的下载根目录
        image = res['image']
        file = res['file']  
        type = self.property['type']
        
        fakeLength = -1
        
        # 下载到目录
        if type in ['file', 'file[]'] :
            dirName = os.path.join(resRoot, file)
            

            
        # 开始下载相应的property
        
        data = self.data
        
        # 不完整的数据
        if data.has_key(self.property['name']) == False:
            return
        if data[self.property['name']] == None:
            return
        
        if type in ['image[]', 'file[]']:
            # 多个文件
            for i in range(0, len(data[self.property['name']])):
                img = data[self.property['name']][i]    
                # 判断是否已经下载
                if int(img['length']) > 0:
                    continue
                if len(img['url']) < 5:
                    continue
                
                # 取属性值并下载
                url = img['url']
                fileName, fileLength = None, None
                
                if img.has_key('fails') == False:
                    img['fails'] = 0  # 失败次数
                else:
                    failsCount = int(img['fails'])
                    if failsCount > MAX_FAILS_ALLOW :
                        continue    
                
                    
                try:
                    # 是否种子文件
                    if canDownload(url):
                        fileName, fileLength = TorrentDownloader(url).download(dirName)
                    else:
                        self.handler.baseDir = os.path.join(resRoot, image)
                        fileName, fileLength = self.handler.getImage(url)
                        self.create_thumbnail(os.path.join(self.handler.baseDir, fileName), type)
                        print url, 'downloaded'
                    
                    
                    # 判断指定长度
                    if img.has_key('fakeLength'):
                        fakeLength = int(img['fakeLength'])
                        
                    if fakeLength != -1:
                        fileLength = fakeLength
                    
                    
                    # 保存下载信息
                    imgJson = {'url' : url, 'file' : fileName, 'length' :  fileLength, 'fails' : img['fails']}
                    img = imgJson
                
                except DownloadException, ex:
                    print ex.msg
                    fileName, fileLength = '404.jpg',10240
                    self.create_thumbnail(os.path.join(self.handler.baseDir, fileName), type)
                    img['state'] = 'DownloadException'
                    img['error'] = str(ex)
                    img['fails'] = img['fails'] + 1
                except IOError , ex:
                    print ex, url
                    img['state'] = 'IOError'
                    img['error'] = str(ex)
                    img['fails'] = img['fails'] + 1
                except InvalidURL, ex:
                    # url 格式不对
                    print '[InvalidURL]' , url
                    img['error'] = str(ex)
                    img['state'] = 'InvalidURL', url
                    # 修正格式
                    img['url'] = img['url'].replace(' ', '')
                    img['url'] = img['url'].replace(':/', '/')
                    img['fails'] = img['fails'] + 1
                    img['error'] = str(ex)
                except UnicodeError, ex:
                    print ex
                    img['state']= 'UnicodeError'
                    img['error'] = str(ex)
                    img['fails'] = img['fails'] + 1
                finally:    
                    # 修改data
                    data[self.property['name']][i] = img
                    db.save_item_data(self.item.get_property('collection'), data)
                
        else : # 单个文件
            
            # 通过判断是否存在image:name字段值， 判断是否已经下载
            if data.has_key(self.property['name']) == False:
                print 'not exists "', self.property['name'], '" field , skip'
                return 
            if int(data[self.property['name']]['length']) > 0:
                return
            if len(data[self.property['name']]['url']) < 5:
                return
            
            # 取属性值并下载
            url = data[self.property['name']]['url']
            print 'downloading ', url
            # 是否种子文件
            if canDownload(url):
                fileName, fileLength = TorrentDownloader(url).download(dirName)
            else:
                self.handler.baseDir = os.path.join(resRoot, image)
                fileName, fileLength = self.handler.getImage(url)
                self.create_thumbnail(os.path.join(self.handler.baseDir, fileName), type)
                
            # 判断指定长度
            if data[self.property['name']].has_key('fakeLength'):
                fakeLength = int(data[self.property['name']]['fakeLength'])
                
            if fakeLength != -1:
                fileLength = fakeLength
                        
            imgJson = {'url' : url, 'file' : fileName, 'length' :  fileLength}
            data[self.property['name']] = imgJson
            db.save_item_data(self.item.get_property('collection'), data) 
    
    # 缩略图    
    def create_thumbnail(self, file, type):
        if type not in ('image', 'image[]'):
            return
        if self.item.get_property('resource').has_key('thumbnail') == False:
            return
        org = file
        destDir = os.path.join(self.item.get_property('resource')['root'], self.item.get_property('resource')['thumbnail'])
        destName = 'crop_' + os.path.basename(file)
        t = Thumbnail(org,destDir,destName)    
        t.create(True)
        
    def is_need_download(self):
        return self.property['type'] in NEED_DOWNLOAD
    
    
if __name__ == '__main__':
#    blade = db.db['data_blade'].find( {'bladeDetailUrl' : 'http://www.tabletennisdb.com/blade/../blade/andro-blax-off.html'})[0]
#    item = get_item_by_name('tabletennisdb')
    blade = db.db['data_aisex'].find( {'postDetailUrl' : 'http://www.aisex.com/bt/htm_data/4/1109/484598.html'})[0]
    item = get_item_by_name('aisex_asia')
    prop = item.get_property('properties')[-2]
    handler = HttpHandler(item.get_property('resource')['root'])
    obj = DataObj(blade, prop, item, handler)
    obj.download()
    